HashMap底层实现原理详解

您所在的位置:网站首页 hashmap put底层原理 HashMap底层实现原理详解

HashMap底层实现原理详解

2023-09-20 16:43| 来源: 网络整理| 查看: 265

文章目录 一、快速入门1.HashMap的常用方法2.HashMap的几个重要知识点 二、JDK7与JDK8的HashMap区别三、HashMap的容量与扩容机制1.HashMap的默认负载因子2.HashMap的扩容机制3.HashMap中散列表数组初始长度 四、HashMap的结构五、HashMap存储原理与存储流程1.HashMap存储原理2.HashMap存储流程 六、jdk8中HashMap为什么要引入红黑树?七、扩容后的新table数组,那老数组中的这个数据怎么迁移呢

一、快速入门

示例:有一定基础的小伙伴们可以选择性的跳过该步骤

HashMap是Java程序员使用频率最高的用于映射键值对(key和value)处理的数据类型。随着JDK版本的跟新,JDK1.8对HashMap底层的实现进行了优化,列入引入红黑树的数据结构和扩容的优化等。本文结合JDK1.7和JDK1.8的区别,深入探讨HashMap的数据结构实现和功能原理。 Java为数据结构中的映射定义了一个接口java.uti.Map,此接口主要有四个常用的实现类,分别是HashMap,LinkedHashMap,Hashtable,TreeMap,IdentityHashMap。本篇文章主要讲解HashMap以及底层实现原理。

1.HashMap的常用方法 // Hashmap存值:----------------------------------》 .put("key","value"); ----------》无返回值。 // // Hashmap取值:----------------------------------》 .get("key");-------------------》 返回Value的类型。 // // Hashmap判断map是否为空:-----------------------》 .isEmpty(); -------------------》返回boolean类型。 // // Hashmap判断map中是否存在这个key:--------------》.containsKey("key");------------》返回boolean类型。 // // Hashmap判断map中是否含有value:----------------》.containsValue("value");-------》返回boolean类型。 // // Hashmap删除这个key值下的value:----------------》.remove("key");-----------------》返回Value的类型。 // // Hashmap显示所有的value值:---------------------》.values(); --------------------》返回Value的类型。 // // Hashmap显示map里的值得数量:-------------------》.size(); ----------------------》返回int类型 // // HashMap显示当前已存的key:---------------------》 .keySet();-------------------》返回Key的类型数组。 // // Hashmap显示所有的key和value:-----------------》.entrySet());------------------》返回Key=Value类型数组。 // // Hashmap添加另一个同一类型的map:--------------》.putAll(map); -----------------》(参数为另一个同一类型的map)无返回值。 // // Hashmap删除这个key和value:------------------》.remove("key", "value");-------》(如果该key值下面对应的是该value值则删除)返回boolean类型。 // // Hashmap替换这个key对应的value值(JDK8新增):---》.replace("key","value");-------》返回被替换掉的Value值的类型。 // // 克隆Hashmap:-------------------------------》.clone(); ---------------------》返回object类型。 // // 清空Hashmap:-------------------------------》.clear(); ---------------------》无返回值。 2.HashMap的几个重要知识点

HashMap是无序且不安全的数据结构。

HashMap 是以key–value对的形式存储的,key值是唯一的(可以为null),一个key只能对应着一个value,但是value是可以重复的。

HashMap 如果再次添加相同的key值,它会覆盖key值所对应的内容,这也是与HashSet不同的一点,Set通过add添加相同的对象,不会再添加到Set中去。

HashMap 提供了get方法,通过key值取对应的value值,但是HashSet只能通过迭代器Iterator来遍历数据,找对象。

二、JDK7与JDK8的HashMap区别

既然讲HashMap,那就不得不说一下JDK7与JDK8(及jdk8以后)的HashMap有什么区别:

jdk8中添加了红黑树,当链表长度大于等于8的时候链表会变成红黑树链表新节点插入链表的顺序不同(jdk7是插入头结点,jdk8因为要把链表变为红 黑树所以采用插入尾节点)hash算法简化 ( jdk8 )resize的逻辑修改(jdk7会出现死循环,jdk8不会) 三、HashMap的容量与扩容机制 1.HashMap的默认负载因子 /** * The load factor used when none specified in constructor. */ static final float DEFAULT_LOAD_FACTOR = 0.75f; /** *默认的负载因子是0.75f,也就是75% 负载因子的作用就是计算扩容阈值用,比如说使用 *无参构造方法创建的HashMap 对象,他初始长度默认是16 阈值 = 当前长度 * 0.75 就 *能算出阈值,当当前长度大于等于阈值的时候HashMap就会进行自动扩容 */

面试的时候,面试官经常会问道一个问题:为什么HashMap的默认负载因子是0.75,而不是0.5或者是整数1呢? 答案有两种:

阈值(threshold) = 负载因子(loadFactor) x 容量(capacity) 根据HashMap的扩容机制,他会保证容量(capacity)的值永远都是2的幂 为了保证负载因子x容量的结果是一个整数,这个值是0.75(4/3)比较合理,因为这个数和任何2的次幂乘积结果都是整数。

理论上来讲,负载因子越大,导致哈希冲突的概率也就越大,负载因子越小,费的空间也就越大,这是一个无法避免的利弊关系,所以通过一个简单的数学推理,可以测算出这个数值在0.75左右是比较合理的

2.HashMap的扩容机制

写数据之后会可能触发扩容,HashMap结构内,我记得有一个记录当前数据量的字段,这个数据量字段到达扩容阈值的话,它就会触发扩容的操作

阈值(threshold) = 负载因子(loadFactor) x 容量(capacity) 当HashMap中table数组(也称为桶)长度 >= 阈值(threshold) 就会自动进行扩容。 扩容的规则是这样的,因为table数组长度必须是2的次方数,扩容其实每次都是按照上一次tableSize位运算得到的就是做一次左移1位运算, 假设当前tableSize是16的话 16转为二进制再向左移一位就得到了32 即 16


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3